
13.01.2017, 14:36
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 157
|
|
Передача файла на сервер ajax
Добрый день! Пытаюсь написать обработчик формы через которую пользователь оставляет отзыв и может прикрепить фотографию.
Все отлично работает кроме загрузки фотографии, она попросту не загружается, а почему я не понимаю, все делаю правильно вроде бы, а она не грузиться хоть ты убей, при этом консоль нечего не говорит, успешно возвращается success, и network в консоли говорит что все "ок, информация передана".
Может быть причина в php, может в клиенте, я уже не знаю, прошу взглянуть на мои скрипты, может вы поймете где у меня ошибка:
Разметка формы:
<form id="contact-form" enctype="multipart/form-data" method="post" action="comments/add_comments">
<input type="name" placeholder="Ваше имя" name="comments_name">
<input type="text" placeholder="Город/поселок" name="comments_city">
<input type="email" placeholder="Ваш e-mail адрес" name="comments_email">
<input type="tel" placeholder="Ваш номер телефона" name="comments_phone">
<textarea placeholder="Пожалуйста напишите Ваш отзыв, здесь" name="comments_message" rows="3"></textarea><br>
<br>
<label class="control-label">Вы можете поделиться фотографиями с отдыха:</label><br>
<br>
<input type="file" name="img">
<br>
<button type="submit" class="button--8">ОСТАВИТЬ ОТЗЫВ</button>
</form>
JS обработчик формы:
$("form#contact-form").submit(function(e){
e.preventDefault();
var f = this,
data = $(f.elements).slice(0, -1),
s = $(f.elements).last(),
e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
return !$.trim(this.value)
});
if(e.length) e.addClass('input-error');
else {
s.prop('disabled', 1);
s.end().not(s);
$.ajax({
url: f.action,
type: 'POST',
data: data,
dataType: 'json',
success: function(data) {
thx('open');
create_comments(data);
f.reset();
s.prop('disabled', 0);
e.removeClass('input-error');
$('body').animate(
{
scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
},
500
);
}
});
}
});
Обработчик на сервере:
//КОНТРОЛЛЕР
function add_comments() {
$config['upload_path'] = './photo/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['max_size'] = '3000';
$config['encrypt_name'] = TRUE;
$config['remove_spaces'] = TRUE;
$this->load->library('upload', $config);
$this->upload->do_upload();
$image_data = $this->upload->data();
$comments['name'] = $_POST['comments_name'];
$comments['city'] = $_POST['comments_city'];
$comments['email'] = $_POST['comments_email'];
$comments['phone'] = $_POST['comments_phone'];
$comments['comment'] = $_POST['comments_message'];
$comments['img'] = $image_data['file_name'];
$comment_id = $this->main_model->new_comments($comments);
$comment = array();
if ($comment_id)
{
$comment = $this->main_model->get_comments_limit(0,1);
}
echo json_encode($comment);
}
// МОДЕЛЬ
function new_comments($comments){
$array = array(
'date' => date("Y-m-d H:i:s", time()),
'name' => $comments['name'],
'city' => $comments['city'],
'email' => $comments['email'],
'phone' => $comments['phone'],
'comment' => $comments['comment'],
'img' => $comments['img']
);
$this->db->insert('comments', $array);
return $this->db->insert_id();
}
Заранее благодарен за любую помощь
P.S. Серверная часть написана на php-фреймворке Codignaiter
|
|

13.01.2017, 14:48
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
В показанном коде ничего нет о самой загрузке файлов, ищите здесь
$this->load->library('upload', $config);
$this->upload->do_upload();
etc ...
|
|

13.01.2017, 15:02
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от smart-create
|
это не совсем так
|
Даже так? Ну-ну, а ничего, что информацию о файлах загруженных нужно искать в массиве $_FILES, чего в вашем коде нет?
Ищите там где указано, загрузкой у вас занимается класс указанный. Вот и разбираться начинайте с него.
|
|

13.01.2017, 16:06
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 157
|
|
Сообщение от laimas
|
Даже так? Ну-ну, а ничего, что информацию о файлах загруженных нужно искать в массиве $_FILES, чего в вашем коде нет?
Ищите там где указано, загрузкой у вас занимается класс указанный. Вот и разбираться начинайте с него.
|
Я понимаю о чем вы говорите, но у Codignaiter есть свой подход к загрузке фалов, весь замес происходит тут:
function add_comments() {
$config['upload_path'] = './photo/'; // задаем путь для загрузки
$config['allowed_types'] = 'gif|jpg|png|jpeg'; // задаем допустимые типы загружаемых файлов
$config['max_size'] = '3000'; // задаем максимальный допустимый размер загруженного файла
$config['encrypt_name'] = TRUE; // переименовываем загружаемый файл в набор символов типа: "a86e4526e164492ebe858ed9a87522d8.png"
$config['remove_spaces'] = TRUE; // удаляем пробелы в названии файла и меняем их на "_"
$this->load->library('upload', $config); // загружаем массив со всеми указанными параметрами в библиотеку 'upload'
$this->upload->do_upload(); // вызываем функцию из библиотеки 'upload' которая и загружает изображения со всеми указанными выше параметрами
$image_data = $this->upload->data(); // получаем имя загружаемого изображения
$comments['name'] = $_POST['comments_name'];
$comments['city'] = $_POST['comments_city'];
$comments['email'] = $_POST['comments_email'];
$comments['phone'] = $_POST['comments_phone'];
$comments['comment'] = $_POST['comments_message'];
$comments['img'] = $image_data['file_name'];
$comment_id = $this->main_model->new_comments($comments);
$comment = array();
if ($comment_id)
{
$comment = $this->main_model->get_comments_limit(0,1);
}
echo json_encode($comment);
}
И что самое главное, он 100% работает. Это можно увидеть если не навешивать на форму мой jq-обработчик:
$("form#contact-form").submit(function(e){
e.preventDefault();
var f = this,
data = $(f.elements).slice(0, -1),
s = $(f.elements).last(),
e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
return !$.trim(this.value)
});
if(e.length) e.addClass('input-error');
else {
s.prop('disabled', 1);
s.end().not(s);
$.ajax({
url: f.action,
type: 'POST',
data: data,
dataType: 'json',
success: function(data) {
thx('open');
create_comments(data);
f.reset();
s.prop('disabled', 0);
e.removeClass('input-error');
$('body').animate(
{
scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
},
500
);
}
});
}
});
Вы можете сами в этом убедиться перейдя по ссылке http://villabavaria.net/comments
Самый последний комментарий там, оставлен мной, только что, можно увидеть что картинка там есть. Если есть желание оставьте совой отзыв и убедитесь.
Одним словом все работает как нужно, до тех пор пока я не навешиваю обработчик с аяксом на форму. Если навесить его, то картинка перестает загружаться
|
|

13.01.2017, 16:21
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Мне не нужно никуда переходить я и без этого знаю, что загрузкой занимается не код показанный, а класс указанный. Читайте мануал о загрузке файлов на сервер.
На клиенте же, чтобы передать файлы методом $.ajax jQuey, этому методу обязательно нужно указать параметры: contentType: false и processData: false, в противном случае форма будет отправлена не как multipart/form-data, что требуется при отправке файлов, а как текст application/x-www-form-urlencoded.
Если бы заглянули куда вам говорилось или бы открыли отладчик браузера, ясна бы была причина, вы же пытаетесь икать ее там, где ее не увидеть.
PS. Сразу добавлю, что следующая причина "все равно ..." кроется здесь: data: data.
Последний раз редактировалось laimas, 13.01.2017 в 16:46.
|
|

13.01.2017, 16:58
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сюда, почитайте и без всяких контроллеров, простым кодом, отдельным файлом, на локальном сервере потренируйтесь пока не уясните как работает это. А уж потом во что угодно... Странно, что есть CMS, и если есть готовое для асинхронной загрузки, использовать нечто свое не работающее.
|
|

13.01.2017, 18:20
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 157
|
|
Сообщение от laimas
|
Странно, что есть CMS, и если есть готовое для асинхронной загрузки, использовать нечто свое не работающее.
|
laimas, хотите смейтесь надо мной, я готов уже признать что я тупой. Не понимаю я логики, а готовое не использую потому что хочу сам разобраться, я уже нашел много вариантов сделанных с помощью различных плагинов, но хотелось бы понять самому, что пока не получается, воспользовавшись информацией по ссылке которую Вы мне прислали, я сделал у себя вот так:
$("form#contact-form").submit(function(e){
e.preventDefault();
var f = this,
data = new FormData(this),
s = $(f.elements).last(),
e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
return !$.trim(this.value)
});
if(e.length) e.addClass('input-error');
else {
s.prop('disabled', 1);
s.end().not(s);
$.ajax({
url: f.action,
type: 'POST',
data: data,
contentType: false,
processData: false,
cache: false,
dataType: 'json',
success: function(data) {
thx('open');
create_comments(data);
f.reset();
s.prop('disabled', 0);
e.removeClass('input-error');
$('body').animate(
{
scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
},
500
);
}
});
}
});
Сейчас сервер не дает не каких ошибок, все "ОК", данные сервером принимаются в формате:
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_name"
йцу
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_city"
zxczxc
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_email"
qwe@qwe.qwe
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_phone"
123123
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_message"
йцуйцуйцу
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="userfile"; filename="ico_1_(1).png"
Content-Type: image/png
------WebKitFormBoundarySddb9HE5iPuiUvar--
Но что-то все равно не так..., загрузка не происходит, комментарий тоже не сохраняется, да и success попросту не отрабатывается.
Одним словом я снова в тупике, не знаю в какую сторону двигаться, отладчик нечего не говорит, для него все "ОК"
Последний раз редактировалось smart-create, 13.01.2017 в 18:43.
|
|

13.01.2017, 19:00
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Судя по Content-Disposition: form-data; name="userfile"; filename="ico_1_(1).png"
Content-Type: image/png (далее должны следовать бинарные данные файла) файл передается. Далее причины уже на сервере искать надо.
Примеры по ссылке работают? Массив $_FILES показывает информацию о загрузке? Это же самое можно проверить и в классе производящем загрузку.
|
|

13.01.2017, 19:17
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 157
|
|
laimas, нужно было просто протереть глаза..., нашел синтаксическую ошибку в php. Как всегда, крайне признателен Вам за помощь
Чувствую еще годик такого общения и я благодаря Вам диссертацию напишу. Спасибо! 
|
|
|
|